package org.bookshare.document.beans;

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.benetech.event.EventListener;
import org.benetech.util.ViolationCollatingErrorHandler;
import org.benetech.util.ZipContents;
import org.bookshare.document.daisy.OPFPackageFile;
import org.jdom.Document;
import org.jdom.JDOMException;

/**
 * A set of documents for the NIMAS type.
 * @author Reuben Firmin
 */
public final class NIMASDocumentSet extends AbstractDocumentSet<DocumentType.NIMAS> implements HasOPF, HasXML {
    private ZipContents zipContents;

    /**
     * Build the documentset from a zipContents. This object is delegated to
     * by the other methods.
     * @param zipContents the contents of the zip
     * @param fileBasePath the temporary directory
     * @param eventListener The event listener
	 * @param errorHandler The error handler
	 * @throws IOException if file access fails
     */
    public NIMASDocumentSet(final ZipContents zipContents, final File fileBasePath, final EventListener eventListener,
			final ViolationCollatingErrorHandler errorHandler)
    throws IOException
    {
    	super(fileBasePath, DocumentType.NIMAS, eventListener, errorHandler, false);
        this.zipContents = zipContents;
        for (DocumentComponent element : DocumentType.NIMAS.getComponents()) {
            addFiles(element, zipContents.getFilesMatchingPattern(element.getFileRegexp()));
        }
    }

    /**
     * {@inheritDoc}
     */
    public Document getOPFDocument() {
        return getFactory().getOPFDocument();
    }

    /**
     * Get the OPF documents associated with this set.
     * @return never null
     */
    public Document getXMLDocument() {
        return getFactory().getXMLDocument();
    }

    /**
     * Get the the root path of the Xml and Opf File.
     * @return path or excpetion if not in same folder
     */
    public String getOpfXmlRootPath() {
        final File xml = getXMLFile();
        final File opf = getOPFFile();
        if (xml.getParentFile().getAbsolutePath().equals(opf.getParentFile().getAbsolutePath())) {
        	return xml.getParentFile().getAbsolutePath();
        } else {
        	//XXX
        	throw new RuntimeException("xml and opf are not in the same folder");
        }
    }


    /**
     * {@inheritDoc}
     */
    public File getOPFFile() {
        return getFactory().getOPFFile();
    }

    /**
     * Get the XML files associated with this set.
     * @return never null
     */
    public File getXMLFile() {
        return getFactory().getXMLFile();
    }


    /**
     * The image files.
     * @return never null
     */
    public List<File> getImageFiles() {
        return getFiles(DocumentComponent.IMAGE);
    }

    /**
     * The PDF files.
     * @return never null
     */
    public List<File> getPDFFiles() {
        return getFiles(DocumentComponent.PDF);
    }

    /**
     * Other files, i.e. not XML, OPF, Image or PDF.
     * @return never null.
     */
    public List<File> getOtherFiles() {
        return zipContents.getFilesNotMatchingPattern(new String[]{
                DocumentComponent.OPF.getFileRegexp(),
                DocumentComponent.PDF.getFileRegexp(),
                DocumentComponent.XML.getFileRegexp(),
                DocumentComponent.IMAGE.getFileRegexp(), });
    }

    /**
     * Whether a file is contained within the document set.
     * @param fileHref The name of the file.
     * @return True if the file is in the set
     */
    public boolean containsFile(final String fileHref) {
        return zipContents.contains(getOpfXmlRootPath() + File.separator + fileHref);
    }

    /**
     * Whether a file is contained within the document set with ignored case.
     * @param fileHref The name of the file.
     * @return True if the file is in the set
     */

    public boolean containsFileIgnoreCase(final String fileHref) {
        return zipContents.containsIgnoreCase(getOpfXmlRootPath() + File.separator + fileHref);
    }

    /**
     * {@inheritDoc}
     */
    public String getName() {
    	final File opf = getOPFFile();
    	if (opf != null) {
    		final String name = opf.getName();
    		return name.substring(0, name.lastIndexOf("."));
    	}
    	return null;
    }

    /**
     * {@inheritDoc}
     */
	public OPFPackageFile getOPFPackageFile()
	throws JDOMException, IOException
	{
		return getFactory().getOPFPackageFile();
	}
}
